package com.code.miaosha.service;

import com.code.miaosha.mapper.TGoodsInfoMapper;
import com.code.miaosha.model.TGoodsInfo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.Random;

@Service
public class GoodsServiceImpl implements GoodsService {

    @Autowired
    private TGoodsInfoMapper tGoodsInfoMapper;

    @Override
    public void addGoods(TGoodsInfo info) {
        tGoodsInfoMapper.insert(info);
    }

    @Override
    public void deleteGoods(String code) {
        tGoodsInfoMapper.deleteByPrimaryKey(code);
    }

    @Override
    public int getGoodsRest(String code) {
        return tGoodsInfoMapper.getGoodsRest(code);
    }

    // 秒杀服务，修改库存
    @Override
    public boolean updateGoodsAmount(String code, int buys) {
        // 获取商品库存对象
        TGoodsInfo info = tGoodsInfoMapper.selectByPrimaryKey(code);
        // 获取商品库存
        Integer amount = info.getAmount();

        // 如果库存不够直接返回
        if (amount < buys) {
            return false;
        }

        // 直接访问数据库   悲观锁：1398
        // return tGoodsInfoMapper.updateAmount(code, buys) > 0 ? true : false;

        // 乐观锁实现
        /*
         * 基本版本实现：缩短时间了，但是基于version不好的地方在于，如果是老系统就不好搞了，因为需要加一个version字段的，老系统可能都没法加进去；
         * 对于新系统还是可以的；
         **/
        Integer version = info.getVersion();
        // if (tGoodsInfoMapper.updateAmountByVersion(code, buys, version) > 0) { // 基于version
        if (tGoodsInfoMapper.updateAmountByState(code, buys) > 0) { // 基于状态
            return true;
        }
        // 如果更新失败，当前线程休眠，并错峰执行
        waitForLock();
        // 地柜调用方法本身
        return updateGoodsAmount(code, buys);
    }

    private void waitForLock() {
        try {
            // 随机休眠几秒（不能休眠相同时间，因为多个线程休眠同一时间，那大家还是一起被唤醒去执行，这是不合理的，应该错峰执行）
            Thread.sleep(new Random().nextInt(10) + 1);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}
